/**
 * 
 */
package com.wodsy.phoenix.dataservice.cms.aop;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Component;

import com.alibaba.dubbo.common.json.JSON;
import com.wodsy.phoenix.dataobject.cms.model.StatusTaskVo;

/**
 * @deprecated
 * @author bryan
 * 改变对象的上下线状态
 */
@Component
@Aspect
public class ManuallyChangeStatusAop {
	protected  Logger logger = Logger.getLogger(this.getClass());
	@Autowired
    private JmsTemplate jmsTemplate;
    @Autowired
    private Queue statusQueue;
	
	@Around("@annotation(com.wodsy.phoenix.dataservice.cms.aop.AfterManuallyOperation)")
	public Object afterOperation(ProceedingJoinPoint pjp) {
		Object result = null;
		
		Method method = getMethod(pjp);

		AfterManuallyOperation cacheable = (AfterManuallyOperation) method.getAnnotation(com.wodsy.phoenix.dataservice.cms.aop.AfterManuallyOperation.class);
		
		StatusTaskVo stv = new StatusTaskVo();
		
		List<StatusTaskVo> sTaskVos =  parseKey(cacheable,stv, method, pjp.getArgs());
		
		try {
			result = pjp.proceed();
			sendHomePageObjectStatusChangeTopic(sTaskVos);
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return result;
	}
	
	/** 
	 * 是否为null 
	 * 支持所有数据类型
	 * 
	* @Title: isNull 
	* @param result
	* @return    设定文件 
	* @throws 
	*/ 
	private boolean isNull(Object result){
		return result==null|| 
				((result instanceof ArrayList) && ((ArrayList)result).size()<=0) || 
				((result instanceof String) && ("".equals(result))) || 
				((result instanceof LinkedList) && ((LinkedList)result).size()<=0) || 
				((result instanceof HashMap) && ((HashMap)result).size() <=0) || 
				((result instanceof HashSet) && ((HashSet)result).size() <=0) || 
				((result instanceof List) && ((List)result).size()<=0 ) || 
				((result instanceof Map) && ((Map)result).size()<=0 )  ||
				((result instanceof Set) && ((Set)result).size()<=0 ) ;
	}
	/**
	 * 获取被拦截方法对象
	 * 
	 * MethodSignature.getMethod() 获取的是顶层接口或者父类的方法对象 而缓存的注解在实现类的方法上
	 * 所以应该使用反射获取当前对象的方法对象
	 */
	public Method getMethod(ProceedingJoinPoint pjp) {
		Signature signature = pjp.getSignature();
		MethodSignature methodSignature = (MethodSignature) signature;
		Method method = methodSignature.getMethod();
		return method;

	}
	
	/**
	 * 获取缓存的key key 定义在注解上，支持SPEL表达式
	 * 
	 * @param
	 * @return
	 */
	private List<StatusTaskVo> parseKey(AfterManuallyOperation cacheable,StatusTaskVo stv, Method method, Object[] args) {
		// 获取被拦截方法参数名列表(使用Spring支持类库)
		LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
		String[] paraNameArr = u.getParameterNames(method);

		// 使用SPEL进行key的解析
		ExpressionParser parser = new SpelExpressionParser();
		// SPEL上下文
		StandardEvaluationContext context = new StandardEvaluationContext();
		// 把方法参数放入SPEL上下文中
		for (int i = 0; i < paraNameArr.length; i++) {
			Object o = args[i];
			//System.out.println("bbbbbxxx:"+o);
			Object t = "";
			if (o != null) {
				/*if(o instanceof Integer || o instanceof String || o instanceof Long || o instanceof Byte || o instanceof Boolean || o instanceof Float || o instanceof Double || o instanceof Character){
					t = gson.toJson(o); 
				}else{
					t = o;
				}*/
				t = o;
			} else {
				// continue;
			}
			context.setVariable(paraNameArr[i], t); 
		}
		
		Object temp = new Object();
		try {
			Expression exp = parser.parseExpression(cacheable.objectType());
			temp = exp.getValue(context, Object.class);
			Integer type = (Integer) temp;
			
			exp = parser.parseExpression(cacheable.objectStatus());
			temp = exp.getValue(context, Object.class);
			Integer status = (Integer) temp;
			
			exp = parser.parseExpression(cacheable.objectId());
			temp = exp.getValue(context, Object.class);
			List<StatusTaskVo> sTaskVos = new ArrayList<StatusTaskVo>();
			Integer[] ids = (Integer[]) temp;
			StatusTaskVo stv_tmp = null;
			for (Integer iit : ids) {
				stv_tmp = new StatusTaskVo();
				stv_tmp.setId(iit);
				stv_tmp.setStatus(status);
				stv_tmp.setObjType(type);
				sTaskVos.add(stv_tmp);
			}
			
			return sTaskVos;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	private boolean sendHomePageObjectStatusChangeTopic(final List<StatusTaskVo> stvs) {
        try {
            logger.info("start to send Status update Queue to " + statusQueue.getQueueName() );
            jmsTemplate.send(statusQueue, new MessageCreator(){

                @Override
                public Message createMessage(Session session)
                        throws JMSException {
                	TextMessage message = null;
					try {
						for (StatusTaskVo statusTaskVo : stvs) {
							message = session   
							        .createTextMessage(JSON.json(statusTaskVo));
							message.setJMSType("");
						}
					} catch (IOException e) {
						e.printStackTrace();
					}  
                	return message;
                }
            });
            return true;
        } catch (Exception e) {
        	e.printStackTrace();
            logger.error("Error: send Status failure:" + e.getMessage(), e);
            return false;
        }
    }
	
}
